home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xarchie-2.0.9 / FWF / Dir / DirMgr.c < prev    next >
C/C++ Source or Header  |  1995-06-18  |  12KB  |  489 lines

  1. /****************************************************************************
  2.  
  3.     DirMgr.c
  4.  
  5.     This file contains the C code to implement the DirectoryMgr system.
  6.  
  7.     This system is intended to manage filtered and sorted directory
  8.     lists.
  9.  
  10.  ****************************************************************************/
  11. /*
  12.  * Copyright 1990,1991,1992 Brian Totty
  13.  * 
  14.  * Permission to use, copy, modify, distribute, and sell this software
  15.  * and its documentation for any purpose is hereby granted without fee,
  16.  * provided that the above copyright notice appears in all copies and that
  17.  * both that copyright notice and this permission notice appear in
  18.  * supporting documentation, and that the name of Brian Totty or
  19.  * University of Illinois not be used in advertising or publicity
  20.  * pertaining to distribution of the software without specific, written
  21.  * prior permission.  Brian Totty and University of Illinois make no
  22.  * representations about the suitability of this software for any
  23.  * purpose.  It is provided "as is" without express or implied warranty.
  24.  *
  25.  * Brian Totty and University of Illinois disclaim all warranties with
  26.  * regard to this software, including all implied warranties of
  27.  * merchantability and fitness, in no event shall Brian Totty or
  28.  * University of Illinois be liable for any special, indirect or
  29.  * consequential damages or any damages whatsoever resulting from loss of
  30.  * use, data or profits, whether in an action of contract, negligence or
  31.  * other tortious action, arising out of or in connection with the use or
  32.  * performance of this software.
  33.  *
  34.  * Author:
  35.  *     Brian Totty
  36.  *     Department of Computer Science
  37.  *     University Of Illinois at Urbana-Champaign
  38.  *    1304 West Springfield Avenue
  39.  *     Urbana, IL 61801
  40.  * 
  41.  *     totty@cs.uiuc.edu
  42.  *     
  43.  */ 
  44.  
  45. #include <DirMgr.h>
  46.  
  47. #ifndef NO_REGEXP
  48. #include <RegExp.h>
  49. #endif
  50.  
  51. #define    DIR_MGR_FSM_SIZE 1024
  52.  
  53. /*---------------------------------------------------------------------------*
  54.  
  55.                    S I M P L E    I N T E R F A C E
  56.  
  57.  *---------------------------------------------------------------------------*/
  58.  
  59. DirectoryMgr *DirectoryMgrSimpleOpen(path,sort_type,pattern)
  60. char *path;
  61. int sort_type;
  62. char *pattern;
  63. {
  64.     DirectoryMgr *dm;
  65.     PFI f_func,s_func;
  66.     char *f_data;
  67.  
  68.     if (pattern == NULL) pattern = "*";
  69.     if (!DirectoryMgrSimpleFilterFunc(pattern,&f_func,&f_data))
  70.     {
  71.         return(NULL);
  72.     }
  73.     if (!DirectoryMgrSimpleSortingFunc(sort_type,&s_func))
  74.     {
  75.         free(f_data);
  76.         return(NULL);
  77.     }
  78.     dm = DirectoryMgrOpen(path,s_func,f_func,f_data,TRUE);
  79.     return(dm);
  80. } /* End DirectoryMgrSimpleOpen */
  81.  
  82.  
  83. int DirectoryMgrSimpleRefilter(dm,pattern)
  84. DirectoryMgr *dm;
  85. char *pattern;
  86. {
  87.     PFI f_func;
  88.     char *f_data;
  89.  
  90.     if (!DirectoryMgrSimpleFilterFunc(pattern,&f_func,&f_data))
  91.     {
  92.         return(FALSE);
  93.     }
  94.     DirectoryMgrRefilter(dm,f_func,f_data,TRUE);
  95.     return(TRUE);
  96. } /* End DirectoryMgrSimpleRefilter */
  97.  
  98.  
  99. int DirectoryMgrSimpleResort(dm,sort_type)
  100. DirectoryMgr *dm;
  101. int sort_type;
  102. {
  103.     PFI c_func;
  104.  
  105.     if (!DirectoryMgrSimpleSortingFunc(sort_type,&c_func))
  106.     {
  107.         return(FALSE);
  108.     }
  109.     DirectoryMgrResort(dm,c_func);
  110.     return(TRUE);
  111. } /* End DirectoryMgrSimpleResort */
  112.  
  113.  
  114. /*---------------------------------------------------------------------------*
  115.  
  116.                     N O R M A L    I N T E R F A C E
  117.  
  118.  *---------------------------------------------------------------------------*/
  119.  
  120. DirectoryMgr *DirectoryMgrOpen(path,c_func,f_func,f_data,free_data)
  121. char *path;
  122. PFI c_func,f_func;
  123. char *f_data;
  124. int free_data;
  125. {
  126.     DirectoryMgr *dm;
  127.  
  128.     dm = (DirectoryMgr *)calloc(1,sizeof(DirectoryMgr));
  129.     if (dm == NULL)
  130.     {
  131.         if (free_data && f_data) free(f_data);
  132.         return(NULL);
  133.     }
  134.     if (DirectoryOpen(path,DirectoryMgrDir(dm)) == FALSE)
  135.     {
  136.         free((char *)dm);
  137.         if (free_data && f_data) free((char *)f_data);
  138.         return(NULL);
  139.     }
  140.     DirectoryMgrCompFunc(dm) = c_func;
  141.     DirectoryMgrRefilter(dm,f_func,f_data,free_data);
  142.     return(dm);
  143. } /* End DirectoryMgrOpen */
  144.  
  145.  
  146. void DirectoryMgrClose(dm)
  147. DirectoryMgr *dm;
  148. {
  149.     free((char *)DirectoryMgrData(dm));
  150.     free((char *)DirectoryMgrSortedPtrs(dm));
  151.     if (DirectoryMgrFilterData(dm) && DirectoryMgrFreeFilterData(dm))
  152.     {
  153.         free((char *)DirectoryMgrFilterData(dm));
  154.     }
  155.     DirectoryClose(DirectoryMgrDir(dm));
  156.     free((char *)dm);
  157. } /* End DirectoryMgrClose */
  158.  
  159.  
  160. int DirectoryMgrRefilter(dm,f_func,f_data,f_free)
  161. DirectoryMgr *dm;
  162. PFI f_func;
  163. char *f_data;
  164. int f_free;
  165. {
  166.     if (DirectoryMgrFilterData(dm) && DirectoryMgrFreeFilterData(dm))
  167.     {
  168.         free(DirectoryMgrFilterData(dm));
  169.     }
  170.     DirectoryMgrFilterFunc(dm) = f_func;
  171.     DirectoryMgrFilterData(dm) = f_data;
  172.     DirectoryMgrFreeFilterData(dm) = f_free;
  173.     DirectoryMgrRefresh(dm);
  174.     return(0);    /* gf: what should this be?? */
  175. } /* End DirectoryMgrRefilter */
  176.  
  177.  
  178. int DirectoryMgrRefresh(dm)
  179. DirectoryMgr *dm;
  180. {
  181.     int err,data_size,ptrs_size,i;
  182.     DirEntryCons *head,*tail,*cons;
  183.     DirEntry *dm_data,**dm_ptrs;
  184.     PFI f_func;
  185.     char *f_data;
  186.  
  187.     DirectoryMgrTotalCount(dm) = 0;
  188.     DirectoryMgrFilteredCount(dm) = 0;
  189.     DirectoryRestart(DirectoryMgrDir(dm));
  190.     if (DirectoryMgrData(dm))
  191.         free((char *)DirectoryMgrData(dm));
  192.     if (DirectoryMgrSortedPtrs(dm))
  193.         free((char *)DirectoryMgrSortedPtrs(dm));
  194.     head = NULL;
  195.     f_func = DirectoryMgrFilterFunc(dm);
  196.     f_data = DirectoryMgrFilterData(dm);
  197.     while (1)
  198.     {
  199.         cons = (DirEntryCons *)malloc(sizeof(DirEntryCons));
  200.         if (cons == NULL)
  201.         {
  202.             fprintf(stderr,
  203.                 "DirectoryMgrRefresh: Can't Alloc Cons\n");
  204.             exit(-1);
  205.         }
  206.         err = DirectoryReadNextEntry(DirectoryMgrDir(dm),
  207.                          &(cons->dir_entry));
  208.         if (err == FALSE)
  209.         {
  210.             free((char *)cons);
  211.             break;
  212.         }
  213.         ++ DirectoryMgrTotalCount(dm);
  214.         if ((f_func == NULL) ||
  215.             (f_func && f_func(&(cons->dir_entry),f_data)))
  216.         {
  217.             cons->next = NULL;
  218.             if (head == NULL)
  219.                 head = cons;
  220.                 else
  221.                 tail->next = cons;
  222.             tail = cons;
  223.             ++ DirectoryMgrFilteredCount(dm);
  224.         }
  225.             else            /* Filter Failed */
  226.         {
  227.             free((char *)cons);
  228.         }
  229.     }
  230.  
  231.     data_size = sizeof(DirEntry) * DirectoryMgrFilteredCount(dm);
  232.     ptrs_size = sizeof(DirEntry *) * DirectoryMgrFilteredCount(dm);
  233.     dm_data = (DirEntry *)malloc(data_size);
  234.     dm_ptrs = (DirEntry **)malloc(ptrs_size);
  235.     if ((dm_data == NULL) || (dm_ptrs == NULL))
  236.     {
  237.         fprintf(stderr,"DirectoryMgrRefresh: Out of memory\n");
  238.         exit(1);
  239.     }
  240.     DirectoryMgrData(dm) = dm_data;
  241.     DirectoryMgrSortedPtrs(dm) = dm_ptrs;
  242.  
  243.     for (i = 0; i < DirectoryMgrFilteredCount(dm); i++)
  244.     {
  245.         DirectoryMgrData(dm)[i] = head->dir_entry;
  246.         DirectoryMgrSortedPtrs(dm)[i] = &(DirectoryMgrData(dm)[i]);
  247.         cons = head->next;
  248.         free((char *)head);
  249.         head = cons;
  250.     }
  251.  
  252.     DirectoryMgrResort(dm,DirectoryMgrCompFunc(dm));
  253.     DirectoryMgrRestart(dm);
  254.     return(TRUE);
  255. } /* End DirectoryMgrRefresh */
  256.  
  257.  
  258. void DirectoryMgrResort(dm,c_func)
  259. DirectoryMgr *dm;
  260. PFI c_func;
  261. {
  262.     DirectoryMgrCompFunc(dm) = c_func;
  263.     if (c_func != NULL)
  264.     {
  265.         qsort(DirectoryMgrSortedPtrs(dm),DirectoryMgrFilteredCount(dm),
  266.               sizeof(DirEntry *),DirectoryMgrCompFunc(dm));
  267.     }
  268.     DirectoryMgrRestart(dm);
  269. } /* End DirectoryMgrResort */
  270.  
  271. /*---------------------------------------------------------------------------*
  272.  
  273.                   I T E R A T I O N    C O M M A N D S
  274.  
  275.  *---------------------------------------------------------------------------*/
  276.  
  277. int DirectoryMgrGotoItem(dm,i)
  278. DirectoryMgr *dm;
  279. int i;
  280. {
  281.     if (i < 0 || i >= DirectoryMgrFilteredCount(dm)) return(FALSE);
  282.     DirectoryMgrCurrentIndex(dm) = i;
  283.     return(TRUE);
  284. } /* End DirectoryMgrGotoItem */
  285.  
  286.  
  287. int DirectoryMgrGotoNamedItem(dm,name)
  288. DirectoryMgr *dm;
  289. char *name;
  290. {
  291.     int i;
  292.     DirEntry *entry;
  293.  
  294.     for (i = 0; i < DirectoryMgrFilteredCount(dm); i++)
  295.     {
  296.         entry = DirectoryMgrSortedPtrs(dm)[i];
  297.         if (strcmp(DirEntryFileName(entry),name) == 0)
  298.         {
  299.             DirectoryMgrCurrentIndex(dm) = i;
  300.             return(TRUE);
  301.         }
  302.     }
  303.     return(FALSE);
  304. } /* End DirectoryMgrGotoNamedItem */
  305.  
  306.  
  307. void DirectoryMgrRestart(dm)
  308. DirectoryMgr *dm;
  309. {
  310.     DirectoryMgrCurrentIndex(dm) = 0;
  311. } /* End DirectoryMgrRestart */
  312.  
  313.  
  314. DirEntry *DirectoryMgrCurrentEntry(dm)
  315. DirectoryMgr *dm;
  316. {
  317.     int index;
  318.  
  319.     index = DirectoryMgrCurrentIndex(dm);
  320.     if (index < 0 || index >= DirectoryMgrFilteredCount(dm)) return(NULL);
  321.     return(DirectoryMgrSortedPtrs(dm)[index]);
  322. } /* End DirectoryMgrCurrentEntry */
  323.  
  324.  
  325. DirEntry *DirectoryMgrNextEntry(dm)
  326. DirectoryMgr *dm;
  327. {
  328.     int index;
  329.  
  330.     index = DirectoryMgrCurrentIndex(dm);
  331.     if (index >= DirectoryMgrFilteredCount(dm)) return(NULL);
  332.     ++ DirectoryMgrCurrentIndex(dm);
  333.     return(DirectoryMgrSortedPtrs(dm)[index]);
  334. } /* End DirectoryMgrNextEntry */
  335.  
  336.  
  337. DirEntry *DirectoryMgrPrevEntry(dm)
  338. DirectoryMgr *dm;
  339. {
  340.     int index;
  341.  
  342.     index = DirectoryMgrCurrentIndex(dm) - 1;
  343.     if (index < 0) return(NULL);
  344.     -- DirectoryMgrCurrentIndex(dm);
  345.     return(DirectoryMgrSortedPtrs(dm)[index]);
  346. } /* End DirectoryMgrPrevEntry */
  347.  
  348. /*---------------------------------------------------------------------------*
  349.  
  350.                    U T I L I T Y    F U N C T I O N S
  351.  
  352.  *---------------------------------------------------------------------------*/
  353.  
  354. int DirectoryMgrSimpleFilterFunc(pattern,ff_ptr,fd_ptr)
  355. char *pattern;
  356. PFI *ff_ptr;
  357. char **fd_ptr;
  358. {
  359. #ifndef    NO_REGEXP
  360.     char regexp[2048];
  361.  
  362.     *ff_ptr = DirectoryMgrFilterName;
  363.     *fd_ptr = (char *)malloc(sizeof(char) * DIR_MGR_FSM_SIZE);
  364.     if (*fd_ptr == NULL) return(FALSE);
  365.     RegExpPatternToRegExp(pattern,regexp);
  366.     RegExpCompile(regexp,*fd_ptr,DIR_MGR_FSM_SIZE);
  367. #endif
  368.     return(TRUE);
  369. } /* End DirectoryMgrSimpleFilterFunc */
  370.  
  371.  
  372. int DirectoryMgrSimpleSortingFunc(sort_type,sf_ptr)
  373. int sort_type;
  374. PFI *sf_ptr;
  375. {
  376.     *sf_ptr = NULL;
  377.     switch (sort_type)
  378.     {
  379.         case DIR_MGR_SORT_NONE:
  380.         break;
  381.         case DIR_MGR_SORT_NAME:
  382.         *sf_ptr = DirectoryMgrCompareName;
  383.         break;
  384.         case DIR_MGR_SORT_SIZE_ASCENDING:
  385.         *sf_ptr = DirectoryMgrCompareSizeAscending;
  386.         break;
  387.         case DIR_MGR_SORT_SIZE_DESCENDING:
  388.         *sf_ptr = DirectoryMgrCompareSizeDescending;
  389.         break;
  390.         case DIR_MGR_SORT_NAME_DIRS_FIRST:
  391.         *sf_ptr = DirectoryMgrCompareNameDirsFirst;
  392.         break;
  393.         case DIR_MGR_SORT_ACCESS_ASCENDING:
  394.         *sf_ptr = DirectoryMgrCompareLastAccessAscending;
  395.         break;
  396.         case DIR_MGR_SORT_ACCESS_DESCENDING:
  397.         *sf_ptr = DirectoryMgrCompareLastAccessDescending;
  398.         break;
  399.         default:
  400.         fprintf(stderr,"Bad sort type %d\n",sort_type);
  401.         return(FALSE);
  402.     }
  403.     return(TRUE);
  404. } /* End DirectoryMgrSimpleSortingFunc */
  405.  
  406. /*---------------------------------------------------------------------------*
  407.  
  408.                     S O R T I N G    R O U T I N E S
  409.  
  410.  *---------------------------------------------------------------------------*/
  411.  
  412. int DirectoryMgrCompareName(e1p,e2p)
  413. DirEntry **e1p,**e2p;
  414. {
  415.     return(strcmp(DirEntryFileName(*e1p),DirEntryFileName(*e2p)));
  416. } /* End DirectoryMgrCompareName */
  417.  
  418.  
  419. int DirectoryMgrCompareNameDirsFirst(e1p,e2p)
  420. DirEntry **e1p,**e2p;
  421. {
  422.     if (DirEntryLeadsToDir(*e1p))
  423.     {
  424.         if (!DirEntryLeadsToDir(*e2p)) return(-1);
  425.     }
  426.         else if (DirEntryLeadsToDir(*e2p))
  427.     {
  428.         return(1);
  429.     }
  430.     return(strcmp(DirEntryFileName(*e1p),DirEntryFileName(*e2p)));
  431. } /* End DirectoryMgrCompareNameDirsFirst */
  432.  
  433.  
  434. int DirectoryMgrCompareSizeAscending(e1p,e2p)
  435. DirEntry **e1p,**e2p;
  436. {
  437.     if (DirEntryFileSize(*e1p) < DirEntryFileSize(*e2p))
  438.         return (-1);
  439.         else if (DirEntryFileSize(*e1p) == DirEntryFileSize(*e2p))
  440.         return (0);
  441.         else
  442.         return (1);
  443. } /* End DirectoryMgrCompareSizeAscending */
  444.  
  445.  
  446. int DirectoryMgrCompareSizeDescending(e1p,e2p)
  447. DirEntry **e1p,**e2p;
  448. {
  449.     if (DirEntryFileSize(*e1p) > DirEntryFileSize(*e2p))
  450.         return (-1);
  451.         else if (DirEntryFileSize(*e1p) == DirEntryFileSize(*e2p))
  452.         return (0);
  453.         else
  454.         return (1);
  455. } /* End DirectoryMgrCompareSizeDescending */
  456.  
  457.  
  458. int DirectoryMgrCompareLastAccessAscending(e1p,e2p)
  459. DirEntry **e1p,**e2p;
  460. {
  461.     return((long)DirEntryLastAccess(*e1p) >
  462.            (long)DirEntryLastAccess(*e2p));
  463. } /* End DirectoryMgrCompareLastAccessAscending */
  464.  
  465.  
  466. int DirectoryMgrCompareLastAccessDescending(e1p,e2p)
  467. DirEntry **e1p,**e2p;
  468. {
  469.     return((long)DirEntryLastAccess(*e1p) <
  470.            (long)DirEntryLastAccess(*e2p));
  471. } /* End DirectoryMgrCompareLastAccessDescending */
  472.  
  473. /*---------------------------------------------------------------------------*
  474.  
  475.                      F I L T E R    R O U T I N E S
  476.  
  477.  *---------------------------------------------------------------------------*/
  478.  
  479. int DirectoryMgrFilterName(de,fsm)
  480. DirEntry *de;
  481. char *fsm;
  482. {
  483. #ifndef    NO_REGEXP
  484.     return(RegExpMatch(DirEntryFileName(de),fsm));
  485. #else
  486.     return(TRUE);
  487. #endif
  488. } /* End DirectoryMgrFilterName */
  489.